package cn.amebius.simpledocker.controller;

import cn.amebius.simpledocker.config.DockerFactory;
import cn.amebius.simpledocker.controller.request.AddDockerClientRequest;
import cn.amebius.simpledocker.controller.request.DockerKeyRequest;
import cn.amebius.simpledocker.controller.request.UpdateDockerClientRequest;
import cn.amebius.simpledocker.controller.response.DockerBaseAllInfoResponse;
import cn.amebius.simpledocker.entity.dto.DockerBaseInfoDto;
import cn.amebius.simpledocker.entity.model.DockerClientModel;
import cn.amebius.simpledocker.entity.po.DockerPo;
import cn.amebius.simpledocker.service.DockerService;
import cn.amebius.simpledocker.util.Response;
import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.ws.rs.PathParam;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;

/**
 * Docker的操作接口
 * @author 阿伟
 * @date 2023/7/28 21:30
 */
@RestController
@RequestMapping("/api/docker")
@Slf4j
public class DockerController {

    @Autowired
    DockerFactory dockerFactory;

    @Autowired
    DockerService dockerService;

    @GetMapping("/infoById")
    public Response<DockerClientModel> getInfoById(@PathParam("key") Integer key) {
        DockerClientModel dcm = dockerFactory.getByKey(key);
        DockerClientModel retDcm = new DockerClientModel();
        BeanUtils.copyProperties(dcm,retDcm,"dockerCLient");
        return Response.ok(retDcm);
    }

    @GetMapping("/baseAllInfo")
    public Response<DockerBaseAllInfoResponse> getBaseInfo() {
        DockerBaseAllInfoResponse dbai = new DockerBaseAllInfoResponse();
        ArrayList<DockerBaseInfoDto> dbidList = new ArrayList<>();
        // TODO 根据用户判断小组或者管理进行查询
        int userId = StpUtil.getLoginIdAsInt();
        Map<Integer, DockerClientModel> cg = dockerFactory.getClientGroup();
        dbai.setAlives(dockerFactory.getAlives());
        dbai.setDeads(dockerFactory.getDeads());
        dbai.setTaskTimes(dockerFactory.getTaskTimes());
        Set<Integer> keys = cg.keySet();
        for (Integer key : keys) {
            dbidList.add(getDockerBaseInfoDto(key, cg.get(key)));
        }
        dbai.setTotal(cg.size());
        dbai.setDockerInfos(dbidList);
        return Response.ok(dbai);
    }

    @PostMapping("/pingClient")
    public Response<String> pingClient(@RequestBody DockerKeyRequest dockerKeyRequest) {
        Integer key = dockerKeyRequest.getKey();
        log.info("ping: key = {}",key);
        if (dockerFactory.pingDockerClient(key)) {
            return Response.ok("alive");
        } else {
            return Response.fail("dead");
        }
    }

    @PutMapping("/updateClient")
    public Response<String> updateClient(@RequestBody UpdateDockerClientRequest updateDockerClientRequest) {
        updateDockerClientRequest.checkParameter();
        DockerPo dp = dockerService.editDocker(updateDockerClientRequest);
        Executors.newFixedThreadPool(1).execute(() -> {
            dockerFactory.updateClient(dp);
        });
        return Response.ok("true");
    }

    @PostMapping("/addClient")
    public Response<String> addClient(@RequestBody AddDockerClientRequest addDockerClientRequest) {
        addDockerClientRequest.checkParameter();
        DockerPo dp = dockerService.addDocker(addDockerClientRequest);
        //使用线程池创建一个新的线程来执行dockerFactory.addClient(dp)操作
        Executors.newFixedThreadPool(1).execute(() -> {
            dockerFactory.addClient(dp);
        });
        return Response.ok("添加成功！");
    }

    @DeleteMapping("/deleteClient")
    private Response<String> deleteClient(@RequestBody DockerKeyRequest dockerKeyRequest) {
        dockerService.deleteClient(dockerKeyRequest.getKey());
        Executors.newFixedThreadPool(1).execute(() -> {
            dockerFactory.deleteClient(dockerKeyRequest.getKey());
        });
        return Response.ok("true");
    }

    private static DockerBaseInfoDto getDockerBaseInfoDto(Integer key, DockerClientModel dcm) {
        DockerBaseInfoDto dbid = new DockerBaseInfoDto();
        DockerPo dp = dcm.getDocker();
        dbid.setStatus(dcm.getAlive() ? "alive" : "dead");
        dbid.setKey(key);
        dbid.setType(dp.getType());
        dbid.setHost(dp.getHost());
        dbid.setUsername(dp.getUsername());
        dbid.setName(dp.getName());
        dbid.setPort(dp.getPort());
        dbid.setPassword(dp.getPassword());
        dbid.setCreateTime(dp.getCreateTime());
        return dbid;
    }

}
